package de.velvettear.musiclister.gui;

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTextField;

import de.velvettear.musiclister.database.DatabaseHelper;
import de.velvettear.musiclister.kernel.Statics;
import de.velvettear.musiclister.util.SettingsHelper;

public class MusicLister implements ActionListener {

	private JFrame frmMusiclister;
	private JTextField txt_input;
	private JButton btn_input;
	private JLabel lbl_output;
	private JTextField txt_output;
	private JButton btn_output;
	private JProgressBar pb_progress;
	private JLabel lbl_progress;
	private JButton btn_start;
	private JMenuBar menuBar;
	private JMenu mn_system;
	private JMenuItem mi_settings;
	private JLabel lbl_status;
	private JCheckBox cb_mysql;
	private JCheckBox cb_folder;
	private JMenuItem mi_info;

	private static Vector<String> startArguments;
	private static boolean GUI = true;
	
	public static void main(String[] args) {
		startArguments = new Vector<String>();
		for (String arg : args) {
			startArguments.add(arg);
		}
		
		if (startArguments.contains(Statics.STARTPARAMETER_TERMINAL)) {
			GUI = false;
		}
		
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MusicLister window = new MusicLister();
					window.frmMusiclister.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});	
	}

	public MusicLister() {
		if (GUI) {
			initialize();
		}		
	}
	
	private void initialize() {
		frmMusiclister = new JFrame();
		frmMusiclister.setTitle("MusicLister");
		frmMusiclister.setBounds(100, 100, 450, 300);
		frmMusiclister.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{0, 0, 0};
		gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
		gridBagLayout.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		frmMusiclister.getContentPane().setLayout(gridBagLayout);
		
		JLabel lbl_input = new JLabel("Input-Folder:");
		lbl_input.setFont(new Font("Tahoma", Font.BOLD, 14));
		GridBagConstraints gbc_lbl_input = new GridBagConstraints();
		gbc_lbl_input.anchor = GridBagConstraints.WEST;
		gbc_lbl_input.insets = new Insets(10, 5, 5, 5);
		gbc_lbl_input.gridx = 0;
		gbc_lbl_input.gridy = 0;
		frmMusiclister.getContentPane().add(lbl_input, gbc_lbl_input);
		
		txt_input = new JTextField();
		GridBagConstraints gbc_txt_input = new GridBagConstraints();
		gbc_txt_input.insets = new Insets(0, 5, 5, 5);
		gbc_txt_input.fill = GridBagConstraints.HORIZONTAL;
		gbc_txt_input.gridx = 0;
		gbc_txt_input.gridy = 1;
		frmMusiclister.getContentPane().add(txt_input, gbc_txt_input);
		txt_input.setColumns(10);
		txt_input.setText(SettingsHelper.getInput());
		
		btn_input = new JButton("Change");
		GridBagConstraints gbc_btn_input = new GridBagConstraints();
		gbc_btn_input.insets = new Insets(0, 0, 5, 5);
		gbc_btn_input.gridx = 1;
		gbc_btn_input.gridy = 1;
		frmMusiclister.getContentPane().add(btn_input, gbc_btn_input);
		
		lbl_output = new JLabel("Cover-Folder:");
		lbl_output.setFont(new Font("Tahoma", Font.BOLD, 14));
		GridBagConstraints gbc_lbl_output = new GridBagConstraints();
		gbc_lbl_output.anchor = GridBagConstraints.WEST;
		gbc_lbl_output.insets = new Insets(10, 5, 5, 5);
		gbc_lbl_output.gridx = 0;
		gbc_lbl_output.gridy = 2;
		frmMusiclister.getContentPane().add(lbl_output, gbc_lbl_output);
				
		txt_output = new JTextField();
		GridBagConstraints gbc_txt_output = new GridBagConstraints();
		gbc_txt_output.insets = new Insets(0, 5, 5, 5);
		gbc_txt_output.fill = GridBagConstraints.HORIZONTAL;
		gbc_txt_output.gridx = 0;
		gbc_txt_output.gridy = 3;
		frmMusiclister.getContentPane().add(txt_output, gbc_txt_output);
		txt_output.setColumns(10);
		txt_output.setText(SettingsHelper.getCovers());
		
		btn_output = new JButton("Change");
		GridBagConstraints gbc_btn_output = new GridBagConstraints();
		gbc_btn_output.insets = new Insets(0, 0, 5, 5);
		gbc_btn_output.gridx = 1;
		gbc_btn_output.gridy = 3;
		frmMusiclister.getContentPane().add(btn_output, gbc_btn_output);
		
		cb_mysql = new JCheckBox("MySQL");
		GridBagConstraints gbc_cb_mysql = new GridBagConstraints();
		gbc_cb_mysql.anchor = GridBagConstraints.WEST;
		gbc_cb_mysql.insets = new Insets(0, 0, 5, 5);
		gbc_cb_mysql.gridx = 0;
		gbc_cb_mysql.gridy = 4;
		frmMusiclister.getContentPane().add(cb_mysql, gbc_cb_mysql);
		
		cb_folder = new JCheckBox("Covers");
		GridBagConstraints gbc_cb_folder = new GridBagConstraints();
		gbc_cb_folder.anchor = GridBagConstraints.WEST;
		gbc_cb_folder.insets = new Insets(0, 0, 5, 5);
		gbc_cb_folder.gridx = 0;
		gbc_cb_folder.gridy = 5;
		frmMusiclister.getContentPane().add(cb_folder, gbc_cb_folder);
		cb_folder.addActionListener(this);
		cb_folder.setActionCommand(Statics.ACTION_OUTPUTFOLDER);
		
		btn_start = new JButton("Start");
		GridBagConstraints gbc_btn_start = new GridBagConstraints();
		gbc_btn_start.gridwidth = 2;
		gbc_btn_start.insets = new Insets(10, 5, 10, 5);
		gbc_btn_start.gridx = 0;
		gbc_btn_start.gridy = 6;
		frmMusiclister.getContentPane().add(btn_start, gbc_btn_start);
		
		lbl_progress = new JLabel("Progress:");
		lbl_progress.setFont(new Font("Tahoma", Font.BOLD, 14));
		GridBagConstraints gbc_lbl_progress = new GridBagConstraints();
		gbc_lbl_progress.anchor = GridBagConstraints.WEST;
		gbc_lbl_progress.insets = new Insets(10, 5, 5, 5);
		gbc_lbl_progress.gridx = 0;
		gbc_lbl_progress.gridy = 7;
		frmMusiclister.getContentPane().add(lbl_progress, gbc_lbl_progress);
		
		pb_progress = new JProgressBar();
		pb_progress.setForeground(Color.GREEN);
		GridBagConstraints gbc_pb_progress = new GridBagConstraints();
		gbc_pb_progress.fill = GridBagConstraints.HORIZONTAL;
		gbc_pb_progress.gridwidth = 2;
		gbc_pb_progress.insets = new Insets(0, 5, 10, 5);
		gbc_pb_progress.gridx = 0;
		gbc_pb_progress.gridy = 8;
		frmMusiclister.getContentPane().add(pb_progress, gbc_pb_progress);
		
		btn_input.addActionListener(this);
		btn_input.setActionCommand(Statics.ACTION_INPUT);
		
		btn_output.addActionListener(this);
		btn_output.setActionCommand(Statics.ACTION_OUTPUT);
		
		btn_start.addActionListener(this);
		btn_start.setActionCommand(Statics.ACTION_START);
		
		lbl_status = new JLabel("");
		GridBagConstraints gbc_lbl_status = new GridBagConstraints();
		gbc_lbl_status.anchor = GridBagConstraints.WEST;
		gbc_lbl_status.insets = new Insets(0, 5, 10, 5);
		gbc_lbl_status.gridx = 0;
		gbc_lbl_status.gridy = 9;
		frmMusiclister.getContentPane().add(lbl_status, gbc_lbl_status);
		
		lbl_progress.setVisible(false);
		pb_progress.setVisible(false);
		lbl_output.setVisible(false);
		txt_output.setVisible(false);
		btn_output.setVisible(false);
		
		frmMusiclister.pack();
		frmMusiclister.setResizable(false);
		frmMusiclister.setLocationRelativeTo(null);
		
		menuBar = new JMenuBar();
		frmMusiclister.setJMenuBar(menuBar);
				
		mn_system = new JMenu("System");
		menuBar.add(mn_system);
		
		mi_settings = new JMenuItem("Settings");
		mi_settings.addActionListener(this);
		mi_settings.setActionCommand(Statics.ACTION_SETTINGS);
		mn_system.add(mi_settings);
		
		mi_info = new JMenuItem("Info");
		mi_info.addActionListener(this);
		mi_info.setActionCommand(Statics.ACTION_INFO);
		mn_system.add(mi_info);
	}

	private File getDirectory() {		
		File dir = null;
		
		JFileChooser chooser = new JFileChooser();
		chooser.setDialogTitle("Input-Folder");
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		chooser.setAcceptAllFileFilterUsed(false);
		
		if (chooser.showOpenDialog(frmMusiclister) == JFileChooser.APPROVE_OPTION) {
			dir = chooser.getSelectedFile();
			if (dir.isDirectory()) {
				return dir;
			} else {
				dir = null;
			}
		} 
		
		return dir;
	}
	
	private int getArtistCount() {
		String rootPath = txt_input.getText();
		File rootDir = new File(rootPath);
		String[] artists = rootDir.list();
		return artists.length;
	}
	
	private void createMusicList() {
		SettingsHelper.writeSettings(txt_input.getText(), txt_output.getText());
		
		Vector<String> missingCovers = new Vector<String>();
		
		String rootPath = txt_input.getText();
		System.out.println("rootPath: " + rootPath);
		String coverPath = createCoverFolder();
		System.out.println("coverPath: " + coverPath);
		File rootDir = new File(rootPath);
		String[] artists = rootDir.list();
		artists = sort(artists);
		
		for (String artist : artists) {
			System.out.println("artist: " + artist);
			pb_progress.setValue(pb_progress.getValue() + 1);
			lbl_status.setText(pb_progress.getValue() + " / " + artists.length);
			
			int voteCounter = 0;
			StringBuffer content = new StringBuffer();		
			StringBuffer temp = new StringBuffer();
			
			File artistFolder = new File(rootPath + File.separator + artist);
			String[] albums = artistFolder.list();
			albums = sort(albums);
			
			for (String album : albums) {
				System.out.println("album: " + album);
				voteCounter++;
				boolean hasCover = false;
				content.append("<p>{slider " + album + "|green|closed}</p>");
				content.append("<p>{tab Trackliste}</p>");
				
				File albumFolder = new File(rootPath + File.separator + artist + File.separator + album);
				String[] tracks = albumFolder.list();
				tracks = sort(tracks);
				
				for (String track : tracks) {
					System.out.println("track: " + track);
					if (track.endsWith(".mp3")) {
						temp.append("<p><a href=\"ftp://velvettear.no-ip.org/" + artist + "/" + album + "/" + track + "\">" + track + "</a></p>");						
					} else if (track.contains("cover")) {
						hasCover = true;
						String source = rootPath + File.separator + artist + File.separator + album + File.separator + track;
						String destination = coverPath + File.separator + artist + " - " + album + ".jpg";
						if (exportCovers()) {
							copyFile(source, destination);
						}
						content.append("<p><img class=\"reflect\" style=\"display: block; margin-left: auto; margin-right: auto;\" src=\"images/covers/" + artist + " - " + album + ".jpg\" \" alt=\"\" width=\"250\" height=\"250\" /></p>");
					}
				}	
				
				content.append(temp);
				content.append("<p>{tab Bewertung & Kommentare}</p>");
				content.append("<p>{extravote " + voteCounter + "}</p>");
				content.append("<p></p>");
				content.append("<p>{ccomment on}</p>");
				content.append("<p>{/tabs}</p>");
				
				temp = new StringBuffer();
				
				if (!hasCover) {
					missingCovers.add(artist + " - " + album + ".jpg");
				}
			}
			
			content.append("<p>{/tabs}</p>");
			content.append("<p>{/sliders}</p>");
			
			try {
				if (exportToMySQL()) {
					DatabaseHelper.updateArticle(artist, content.toString());
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		Vector<String> missingArticles = DatabaseHelper.getMissingArticles(artists);
		String message = "Success!";
		if (missingArticles.size() > 0) {
			message += "\n\n Missing articles:\n";
			for (String article : missingArticles) {
				message += "- " + article + "\n";
			}
			message = message.substring(0, message.lastIndexOf("\n"));
		}	
		if (missingCovers.size() > 0) {
			message += "\n\n Missing covers:\n";
			for (String cover : missingCovers) {
				message += "- " + cover + "\n";
			}
			message = message.substring(0, message.lastIndexOf("\n"));
		}
		toggleProgressBar(false);
		showMessage(message);
	}
	
	private String createCoverFolder() {
		String coversDirectory = txt_output.getText();
		
		if (exportCovers()) {
			File covers = new File(coversDirectory);
		
			deleteDirectoryRecursively(covers);
		
			covers.mkdirs();	
		}
		
		return coversDirectory;
	}
	
	private void deleteDirectoryRecursively(File path) {
		if (path.exists()) {
			File[] files = path.listFiles();
			for (File f : files) {
				if (f.isDirectory()) {
					deleteDirectoryRecursively(path);
				} else {
					f.delete();
				}
			}
		}
	}
	
	private void copyFile(String source, String destination) {
		try {
			InputStream input = new FileInputStream(source);
			OutputStream output = new FileOutputStream(destination);
			
			byte[] buffer = new byte[1024];
			int bytesRead;
			while((bytesRead = input.read(buffer)) > 0) {
				output.write(buffer, 0, bytesRead);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void toggleProgressBar(boolean show) {
		if (show) {
			int max = getArtistCount();
			btn_start.setVisible(false);
			lbl_progress.setVisible(true);
			pb_progress.setVisible(true);	
			pb_progress.setValue(0);			
			pb_progress.setMaximum(max);
			lbl_status.setVisible(true);
			lbl_status.setText("0 / " + max);
		} else {
			btn_start.setVisible(true);
			lbl_progress.setVisible(false);
			pb_progress.setVisible(false);
			lbl_status.setVisible(false);
		}
		frmMusiclister.pack();
	}
	
	private void toggleOutput(boolean show) {
		if (show) {
			lbl_output.setVisible(true);
			txt_output.setVisible(true);
			btn_output.setVisible(true);
		} else {
			lbl_output.setVisible(false);
			txt_output.setVisible(false);
			btn_output.setVisible(false);
		}
		frmMusiclister.pack();
	}
	
	private void showMessage(String text) {
		JOptionPane.showMessageDialog(null, text);
	}
	
	private boolean exportToMySQL() {
		return cb_mysql.isSelected();
	}
	
	private boolean exportCovers() {
		return cb_folder.isSelected();
	}
	
	private String[] sort(String[] list) {
		for (int i = 0; i < list.length; i++) {
			for (int j = i + 1; j < list.length; j++) {
				if (list[j].compareTo(list[i]) < 0) {
					String tmp = list[i];
					list[i]= list[j]; 
					list[j] = tmp;
				}
			}
		}
		
		return list;
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals(Statics.ACTION_INPUT)) {
			File dir = getDirectory();
			if (dir != null) {
				txt_input.setText(dir.getAbsolutePath());
			}			
		} else if (e.getActionCommand().equals(Statics.ACTION_OUTPUT)) {
			File dir = getDirectory();
			if (dir != null) {
				txt_output.setText(dir.getAbsolutePath());
			}
		} else if (e.getActionCommand().equals(Statics.ACTION_START)) {
			if (!exportToMySQL() && !exportCovers()) {
				showMessage("No export options are selected!");
				return;
			}
			
			toggleProgressBar(true);
			
			Thread workThread = new Thread(new Runnable() {
				
				@Override
				public void run() {
					createMusicList();					
				}
			});
			workThread.start();			
		} else if (e.getActionCommand().equals(Statics.ACTION_SETTINGS)) {
			Settings settings = new Settings();
			settings.setVisible(true);
		} else if (e.getActionCommand().equals(Statics.ACTION_INFO)) {
			Info info = new Info();
			info.setVisible(true);	
		} else if (e.getActionCommand().equals(Statics.ACTION_OUTPUTFOLDER)) {
			toggleOutput(cb_folder.isSelected());
		}
	}

}
